#!/usr/bin/env python3
# -*- coding: utf-8 -*-

from selenium.common.exceptions import WebDriverException, NoSuchWindowException
from Utils.Logger import Logger


class Browser(object):

    def __init__(self, _driver):
        self.driver = _driver
        self.logger = Logger().get_logger()

    @property
    def page_source(self):
        try:
            self.logger.debug("Get page source code")
            page_source = self.driver.page_source
            return page_source
        except WebDriverException as e:
            self.logger.error("WebDriverException: {0}".format(e)[:-1])
            raise e
        except Exception:
            self.logger.exception("Exception: ", exc_info=True)
            raise

    @property
    def title(self):
        try:
            self.logger.debug("Get page title")
            title = self.driver.title
            return title
        except WebDriverException as e:
            self.logger.error("WebDriverException: {0}".format(e)[:-1])
            raise e
        except Exception:
            self.logger.exception("Exception: ", exc_info=True)
            raise

    @property
    def url(self):
        try:
            self.logger.debug("Get page current url")
            url = self.driver.current_url
            return url
        except WebDriverException as e:
            self.logger.error("WebDriverException: {0}".format(e)[:-1])
            raise e
        except Exception:
            self.logger.exception("Exception: ", exc_info=True)
            raise

    def get_driver(self):
        try:
            self.logger.debug("Get driver object")
            return self.driver
        except WebDriverException as e:
            self.logger.error("WebDriverException: {0}".format(e)[:-1])
            raise e
        except Exception:
            self.logger.exception("Exception: ", exc_info=True)
            raise

    def navigate(self, url):
        try:
            self.logger.debug("Navigate to the wanted page: " + url)
            self.driver.get(url)
        except WebDriverException as e:
            self.logger.error("WebDriverException: {0}".format(e)[:-1])
            raise e
        except Exception:
            self.logger.exception("Exception: ", exc_info=True)
            raise

    def forward(self):
        try:
            self.logger.debug("Forward to the next page")
            self.driver.forward()
        except WebDriverException as e:
            self.logger.error("WebDriverException: {0}".format(e)[:-1])
            raise e
        except Exception:
            self.logger.exception("Exception: ", exc_info=True)
            raise

    def back(self):
        try:
            self.logger.debug("Back to the previous page")
            self.driver.back()
        except WebDriverException as e:
            self.logger.error("WebDriverException: {0}".format(e)[:-1])
            raise e
        except Exception:
            self.logger.exception("Exception: ", exc_info=True)
            raise

    def refresh(self):
        try:
            self.logger.debug("Refresh the current page")
            self.driver.refresh()
        except WebDriverException as e:
            self.logger.error("WebDriverException: {0}".format(e)[:-1])
            raise e
        except Exception:
            self.logger.exception("Exception: ", exc_info=True)
            raise

    def close(self):
        try:
            self.logger.debug("Close the current page")
            self.driver.close()
        except WebDriverException as e:
            self.logger.error("WebDriverException: {0}".format(e)[:-1])
            raise e
        except Exception:
            self.logger.exception("Exception: ", exc_info=True)
            raise

    def quit(self):
        try:
            self.logger.debug("Quit the current browser")
            self.driver.quit()
        except WebDriverException as e:
            self.logger.error("WebDriverException: {0}".format(e)[:-1])
            raise e
        except Exception:
            self.logger.exception("Exception: ", exc_info=True)
            raise

    def set_window_size(self, x, y):
        try:
            self.logger.debug("Set browser window size to {0}*{1}".format(x, y))
            self.driver.set_window_size(x, y)
        except WebDriverException as e:
            self.logger.error("WebDriverException: {0}".format(e)[:-1])
            raise e
        except Exception:
            self.logger.exception("Exception: ", exc_info=True)
            raise

    def maximize_window(self):
        try:
            self.logger.debug("Set browser window to the maximum")
            self.driver.maximize_window()
        except WebDriverException as e:
            self.logger.error("WebDriverException: {0}".format(e)[:-1])
            raise e
        except Exception:
            self.logger.exception("Exception: ", exc_info=True)
            raise

    def minimize_window(self):
        try:
            self.logger.debug("Set browser window to the minimum")
            self.driver.minimize_window()
        except WebDriverException as e:
            self.logger.error("WebDriverException: {0}".format(e)[:-1])
            raise e
        except Exception:
            self.logger.exception("Exception: ", exc_info=True)
            raise

    def new_window(self, url):
        try:
            self.logger.debug("Open new window")
            js = 'window.open("{0}");'.format(url)
            self.driver.execute_script(js)
        except WebDriverException as e:
            self.logger.error("WebDriverException: {0}".format(e)[:-1])
            raise e
        except Exception:
            self.logger.exception("Exception: ", exc_info=True)
            raise

    def switch_to_first_window(self):
        try:
            self.logger.debug("Switch current window to the first window")
            windows = self.driver.window_handles
            self.driver.switch_to.window(windows[0])
        except NoSuchWindowException as e:
            self.logger.error("NoSuchWindowException: {0}".format(e)[:-1])
            raise e
        except WebDriverException as e:
            self.logger.error("WebDriverException: {0}".format(e)[:-1])
            raise e
        except Exception:
            self.logger.exception("Exception: ", exc_info=True)
            raise

    def switch_to_last_window(self):
        try:
            self.logger.debug("Switch current window to the last window")
            windows = self.driver.window_handles
            self.driver.switch_to.window(windows[-1])
        except NoSuchWindowException as e:
            self.logger.error("NoSuchWindowException: {0}".format(e)[:-1])
            raise e
        except WebDriverException as e:
            self.logger.error("WebDriverException: {0}".format(e)[:-1])
            raise e
        except Exception:
            self.logger.exception("Exception: ", exc_info=True)
            raise

    def switch_to_specific_window(self, window_index):
        try:
            self.logger.debug("Switch current window to window {0}".format(window_index))
            windows = self.driver.window_handles
            self.driver.switch_to.window(windows[window_index-1])
        except NoSuchWindowException as e:
            self.logger.error("NoSuchWindowException: {0}".format(e)[:-1])
            raise e
        except WebDriverException as e:
            self.logger.error("WebDriverException: {0}".format(e)[:-1])
            raise e
        except Exception:
            self.logger.exception("Exception: ", exc_info=True)
            raise
